package com.passwd.designencrypt.encrypt;

import com.passwd.designcore.utils.FileUtils;
import com.passwd.designcore.utils.KeyUtils;
import com.passwd.designcore.utils.SMS4;


import java.io.InputStream;
import java.util.ArrayList;

public class EncryptCore {

    public String encryptRun(InputStream fileInputStream) {
        ArrayList<String> arrayList = FileUtils.readFile(fileInputStream);
        String result = "success";
        if (arrayList == null || arrayList.isEmpty()) {
            result = "error";
        }
        try {
            String[] keys = arrayList.get(0).split(",|，");
            String resultEncode = "";
            for (int i = 0; i < keys.length; i++) {
                if (i != 0) {
                    resultEncode += ",";
                }
                resultEncode += encodeWriteFile(keys[i]);
            }

            result = FileUtils.writeFile(resultEncode, KeyUtils.outputEncryptFileName);
        } catch (Exception e) {
            e.printStackTrace();
            result = "error";
        }
        return result;
    }


    /**
     * 加密流程
     *
     * @param key
     * @throws Exception
     */
    private String encodeWriteFile(String key) throws Exception {
        int ENCRYPT = 1;
        SMS4 sms4 = new SMS4();

        byte[] c1 = new byte[16];
        byte[] K3 = new byte[16];
        byte[] fiveResult = new byte[16];

        //文档第一步 将关键字填充至128
        byte[] in = KeyUtils. fillZeroTo128(key);
        // 文档第三步 计算出c1
        sms4.sms4(in, 16, KeyUtils.K1, c1, ENCRYPT);

        //文档第四步
        byte[] c1Left64 = new byte[8];
        for (int i = 0; i < c1.length / 2; i++) { // 取c1 的左64
            c1Left64[i] = c1[i];
        }
        byte[] c1Left128 = KeyUtils.fillZeroTo128(c1Left64);// 将c1 的左64 填充至128
        sms4.sms4(c1Left128, 16, KeyUtils.K2, K3, ENCRYPT);// 计算出K3

        // 第五步
        byte[] S1 = KeyUtils. fillZeroTo128(KeyUtils.S1);// 流密码S1（填充至128比特）
        sms4.sms4(S1, 16, K3, fiveResult, ENCRYPT);// 计算出第五步算法结果
        byte[] T1Right64 = new byte[8];
        for (int i = fiveResult.length / 2; i < fiveResult.length; i++) {// 输出结果取后64比特(右)
            T1Right64[i - fiveResult.length / 2] = fiveResult[i];
        }
        int S1len = KeyUtils.S1.length;
        int T1len = S1len + T1Right64.length;
        byte[] T1Init = new byte[T1len];
        for (int i = 0; (i < T1len) && i < 16; i++) { // 流密码S1和结果的后64比特拼接成T1
            if (i < S1len) {
                T1Init[i] = KeyUtils.S1[i];    // 先左拼S1
            } else {
                T1Init[i] = T1Right64[i - S1len]; // 再右拼T1Right64  ； i-S1len代表 T1Right64要从0角标开始读，所以i需要减去已经跑的S1len长度
            }
        }
        byte[] T1 = T1Init;

        // 第六步 最终密文
        if (T1.length < 16) {
            T1 = KeyUtils. fillZeroTo128(T1Init);// 如果T1长度小于128，就将填充T1至128
        }
        ArrayList list=new ArrayList();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < c1.length; i++) {
            int C1Ele = T1[i] ^ c1[i];
            list.add(C1Ele);
            String hexString = Integer.toHexString(C1Ele); // 将c1和T1异或
            if(i!=0){
                sb.append(".");
            }
            sb.append(hexString);
        }
        System.out.println(list);
        return sb.toString();//将加密结果返回
    }


}
